using System;
using System.Collections.Generic;
using System.Text;

namespace PW.Mini.SlepowronskiJ.Siec.Aktywacja
{
    /// <summary>
    /// Bipolarna sigmoidalna funkcja aktywacji
    /// </summary>
    ///
    /// <remarks> Definicja sigmoidalnej funkcji aktywacji<br />
    /// <code>
    ///                2
    /// f(x) = ------------------ - 1
    ///        1 + exp(-beta * x)
    ///
    ///           2 * beta * exp(-beta * x )
    /// f'(x) = -------------------------------- = beta * (1 - f(x)^2) / 2
    ///           (1 + exp(-beta * x))^2
    /// </code>
    /// </remarks>
    [Serializable]
    class BipolarnaSigmoidalnaFunkcjaAktywacji : IFunkcjaAktywacji
    {
        /// <summary>
        /// parametr sigmoidy
        /// </summary>
		protected double beta = 2.0;


        /// <summary>
        /// pobiera i ustawia wartosc parametru beta
        /// </summary>
		public double Beta
		{
			get { return beta; }
			set { beta = value; }
		}


        public BipolarnaSigmoidalnaFunkcjaAktywacji()
            : base()
        {
            nazwa = "Sigmoida";
            rodzajPolarnosci = SKALOWANIE_BIPOLARNE;
        }

        /// <summary>
        /// Clone the object.
        /// </summary>
        /// <returns>The cloned object.</returns>
        public override object Clone()
        {
            return new BipolarnaSigmoidalnaFunkcjaAktywacji();
        }

        /// <summary>
        /// <code>
        ///                 2
        /// f(x) = ----------------- -1 
        ///         1 + e^(-beta*x)
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f(x)</returns>
        public override double WartoscFunkcji(double x)
		{
			return ( ( 2 / ( 1 + Math.Exp( -beta * x ) ) ) - 1 );
		}

        /// <summary>
        /// <code>
        /// f'(x) = beta * (1 - f(x)^2) / 2
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f'(x)</returns>
        public override double WartoscPochodnejFunkcji(double x)
		{
            double y = WartoscFunkcji(x);

			return ( beta * ( 1 - y * y ) / 2 );
		}

        /// <inheritdoc />
        public override double DerivativeFunction(double b, double y)
        {
            return (beta * (1 - y * y) / 2);
        }

    }
}
